Completed
Push — master ( fc3c01...f1dad4 )
by Sander
11s
created

angular.controller(ꞌCredentialCtrlꞌ)   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 383

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 383
rs 6.4589
cc 7
nc 16
nop 19

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
/**
2
 * Nextcloud - passman
3
 *
4
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
5
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
(function () {
24
	'use strict';
25
26
27
	/**
28
	 * @ngdoc function
29
	 * @name passmanApp.controller:MainCtrl
30
	 * @description
31
	 * # MainCtrl
32
	 * Controller of the passmanApp
33
	 */
34
	angular.module('passmanApp')
35
		.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
36
			'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService', 'CacheService', 'ShareService', 'SharingACL', '$interval', '$filter', '$routeParams', '$sce', '$translate',
37
			function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService, CacheService, ShareService, SharingACL, $interval, $filter, $routeParams, $sce, $translate) {
38
				$scope.active_vault = VaultService.getActiveVault();
39
				if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
40
					if (!$scope.active_vault) {
41
						$location.path('/');
42
					}
43
				} else {
44
					if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
45
						var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
46
						_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
47
						VaultService.setActiveVault(_vault);
48
						$scope.active_vault = _vault;
49
						//@TODO check if vault exists
50
					}
51
				}
52
53
				$scope.show_spinner = true;
54
				var fetchCredentials = function () {
55
					VaultService.getVault({guid: $routeParams.vault_id}).then(function (vault) {
56
						var vaultKey = angular.copy($scope.active_vault.vaultKey);
57
						var _credentials = angular.copy(vault.credentials);
58
						vault.credentials = [];
59
						$scope.active_vault = vault;
60
						$scope.active_vault.vaultKey = vaultKey;
61
						VaultService.setActiveVault($scope.active_vault);
62
						for (var i = 0; i < _credentials.length; i++) {
63
							var _credential = _credentials[i];
64
							try {
65
								if (!_credential.shared_key) {
66
									_credential = CredentialService.decryptCredential(angular.copy(_credential));
67
68
								} else {
69
									var enc_key = EncryptService.decryptString(_credential.shared_key);
70
									_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
71
								}
72
								_credential.tags_raw = _credential.tags;
73
							} catch (e) {
74
75
								NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
76
								//$rootScope.$broadcast('logout');
77
								//SettingsService.setSetting('defaultVaultPass', null);
78
								//.setSetting('defaultVault', null);
79
								//$location.path('/')
80
81
							}
82
							if (_credential.tags) {
83
								TagService.addTags(_credential.tags);
84
							}
85
							_credentials[i] = _credential;
86
						}
87
88
						ShareService.getCredendialsSharedWithUs(vault.guid).then(function (shared_credentials) {
89
							for (var c = 0; c < shared_credentials.length; c++) {
90
								var _shared_credential = shared_credentials[c];
91
								var decrypted_key = EncryptService.decryptString(_shared_credential.shared_key);
92
								var _shared_credential_data;
93
								try {
94
									_shared_credential_data = ShareService.decryptSharedCredential(_shared_credential.credential_data, decrypted_key);
95
								} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
96
97
								}
98
								if (_shared_credential_data) {
99
									delete _shared_credential.credential_data;
100
									_shared_credential_data.acl = _shared_credential;
101
									_shared_credential_data.acl.permissions = new SharingACL(_shared_credential_data.acl.permissions);
102
									_shared_credential_data.tags_raw = _shared_credential_data.tags;
103
									if (_shared_credential_data.tags) {
104
										TagService.addTags(_shared_credential_data.tags);
105
									}
106
									_credentials.push(_shared_credential_data);
107
								}
108
							}
109
							angular.merge($scope.active_vault.credentials, _credentials);
110
							$scope.show_spinner = false;
111
						});
112
					});
113
				};
114
115
				var getPendingShareRequests = function () {
116
					ShareService.getPendingRequests().then(function (shareRequests) {
117
						if (shareRequests.length > 0) {
118
							$scope.incoming_share_requests = shareRequests;
119
							jQuery('.share_popup').dialog({
120
								width: 600,
121
								position: ['center', 90]
122
							});
123
						}
124
					});
125
				};
126
127
128
				var refresh_data_interval = null;
129
				if ($scope.active_vault) {
130
					$scope.$parent.selectedVault = true;
131
					fetchCredentials();
132
					getPendingShareRequests();
133
					refresh_data_interval = $interval(function () {
134
						fetchCredentials();
135
						getPendingShareRequests();
136
					}, 60000 * 5);
137
				}
138
				$scope.$on('$destroy', function () {
139
					$interval.cancel(refresh_data_interval);
140
				});
141
142
143
				$scope.permissions = new SharingACL(0);
144
145
				$scope.hasPermission = function (acl, permission) {
146
					if (acl) {
147
						var tmp = new SharingACL(acl.permission);
148
						return tmp.hasPermission(permission);
149
					} else {
150
						return true;
151
					}
152
153
				};
154
155
				$scope.acceptShareRequest = function (share_request) {
156
					var crypted_shared_key = share_request.shared_key;
157
					var private_key = EncryptService.decryptString(VaultService.getActiveVault().private_sharing_key);
158
159
					private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
160
					crypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
0 ignored issues
show
Bug introduced by
The variable forge seems to be never declared. If this is a global, consider adding a /** global: forge */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
161
					crypted_shared_key = EncryptService.encryptString(crypted_shared_key);
162
163
					ShareService.saveSharingRequest(share_request, crypted_shared_key).then(function () {
164
						var idx = $scope.incoming_share_requests.indexOf(share_request);
165
						$scope.incoming_share_requests.splice(idx, 1);
166
						var active_share_requests = false;
167
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
168
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
169
								active_share_requests = true;
170
							}
171
						}
172
						if (active_share_requests === false) {
173
							jQuery('.ui-dialog').remove();
174
							fetchCredentials();
175
						}
176
					});
177
				};
178
179
				$scope.declineShareRequest = function (share_request) {
180
					ShareService.declineSharingRequest(share_request).then(function () {
181
						var idx = $scope.incoming_share_requests.indexOf(share_request);
182
						$scope.incoming_share_requests.splice(idx, 1);
183
						var active_share_requests = false;
184
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
185
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
186
								active_share_requests = true;
187
							}
188
						}
189
						if (active_share_requests === false) {
190
							jQuery('.ui-dialog').remove();
191
							fetchCredentials();
192
						}
193
					});
194
				};
195
196
197
				$scope.addCredential = function () {
198
					var new_credential = CredentialService.newCredential();
199
					var enc_c = CredentialService.encryptCredential(new_credential);
200
					SettingsService.setSetting('edit_credential', enc_c);
201
					$location.path('/vault/' + $scope.active_vault.guid + '/new');
202
				};
203
204
				$scope.editCredential = function (credential) {
205
					var _credential = angular.copy(credential);
206
					$rootScope.$emit('app_menu', false);
207
					SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
208
					$location.path('/vault/' + $scope.active_vault.guid + '/edit/' + _credential.guid);
209
				};
210
211
				$scope.getRevisions = function (credential) {
212
					var _credential = angular.copy(credential);
213
					$rootScope.$emit('app_menu', false);
214
					SettingsService.setSetting('revision_credential', CredentialService.encryptCredential(_credential));
215
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/revisions');
216
				};
217
218
				$scope.shareCredential = function (credential) {
219
					var _credential = angular.copy(credential);
220
					$rootScope.$emit('app_menu', false);
221
					SettingsService.setSetting('share_credential', CredentialService.encryptCredential(_credential));
222
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/share');
223
				};
224
225
				var notification;
226
				$scope.deleteCredential = function (credential) {
227
					var _credential = angular.copy(credential);
228
					try {
229
						_credential = CredentialService.decryptCredential(angular.copy(credential));
230
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
231
232
					}
233
					_credential.delete_time = new Date().getTime() / 1000;
234
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
235
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
236
							$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
237
						}
238
					}
239
					$scope.closeSelected();
240
					if (notification) {
241
						NotificationService.hideNotification(notification);
242
					}
243
					notification = NotificationService.showNotification($translate.instant('credential.deleted'), 5000,
244
						function () {
245
							CredentialService.updateCredential(_credential).then(function (result) {
246
								if (result.delete_time > 0) {
247
									notification = false;
248
249
								}
250
							});
251
						});
252
253
				};
254
255
				$scope.recoverCredential = function (credential) {
256
					var _credential = angular.copy(credential);
257
					try {
258
						_credential = CredentialService.decryptCredential(angular.copy(credential));
259
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
260
261
					}
262
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
263
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
264
							$scope.active_vault.credentials[i].delete_time = 0;
265
						}
266
					}
267
					_credential.delete_time = 0;
268
					$scope.closeSelected();
269
					if (notification) {
270
						NotificationService.hideNotification(notification);
271
					}
272
					NotificationService.showNotification($translate.instant('credential.recovered'), 5000,
273
						function () {
274
							CredentialService.updateCredential(_credential).then(function () {
275
								notification = false;
276
277
							});
278
						});
279
280
				};
281
282
				$scope.destroyCredential = function (credential) {
283
					var _credential = angular.copy(credential);
284
					CredentialService.destroyCredential(_credential.credential_id).then(function () {
285
						for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
286
							if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
287
								$scope.active_vault.credentials.splice(i, 1);
288
								NotificationService.showNotification($translate.instant('credential.destroyed)'), 5000);
289
								break;
290
							}
291
						}
292
					});
293
				};
294
295
				$scope.view_mode = 'list'; //@TODO make this a setting
296
				$scope.switchViewMode = function (viewMode) {
297
					$scope.view_mode = viewMode;
298
				};
299
300
				$scope.filterOptions = {
301
					filterText: '',
302
					fields: ['label', 'username', 'email', 'password', 'custom_fields']
303
				};
304
305
306
				$scope.filtered_credentials = [];
307
				$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function () {
308
					if (!$scope.active_vault) {
309
						return;
310
					}
311
					if ($scope.active_vault.credentials) {
312
						var credentials = angular.copy($scope.active_vault.credentials);
313
						var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
314
						filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
315
						filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
316
						$scope.filtered_credentials = filtered_credentials;
317
					}
318
				}, true);
319
320
				$scope.selectedtags = [];
321
				var to;
322
				$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
323
					var _selectedTags = [];
324
					for (var x = 0; x < _sTags.length; x++) {
325
						_selectedTags.push(_sTags[x].text);
326
					}
327
					$scope.selectedtags = _selectedTags;
328
					$timeout.cancel(to);
329
					if (_selectedTags.length > 0) {
330
						to = $timeout(function () {
331
							if ($scope.filtered_credentials) {
332
								var _filtered_tags = [];
333
								for (var i = 0; i < $scope.filtered_credentials.length; i++) {
334
									var tags = $scope.filtered_credentials[i].tags_raw;
335
									for (var x = 0; x < tags.length; x++) {
336
										var tag = tags[x].text;
337
										if (_filtered_tags.indexOf(tag) === -1) {
338
											_filtered_tags.push(tag);
339
										}
340
									}
341
								}
342
343
								$rootScope.$emit('limit_tags_in_list', _filtered_tags);
344
							}
345
						}, 50);
346
					}
347
				});
348
349
				$scope.delete_time = 0;
350
				$scope.showCredentialRow = function (credential) {
351
					if ($scope.delete_time === 0) {
352
						return credential.delete_time === 0;
353
					} else {
354
						return credential.delete_time > $scope.delete_time;
355
					}
356
357
				};
358
359
				$rootScope.$on('set_delete_time', function (event, time) {
360
					$scope.delete_time = time;
361
				});
362
363
				$scope.setDeleteTime = function (delete_time) {
364
					$scope.delete_time = delete_time;
365
				};
366
367
				$scope.selectedCredential = false;
368
				$scope.selectCredential = function (credential) {
369
					if(credential.description) {
370
						credential.description_html = $sce.trustAsHtml(angular.copy(credential.description).replace("\n", '<br />'));
371
					}
372
					$scope.selectedCredential = angular.copy(credential);
373
					$rootScope.$emit('app_menu', true);
374
				};
375
376
				$scope.closeSelected = function () {
377
					$rootScope.$emit('app_menu', false);
378
					$scope.selectedCredential = false;
379
				};
380
381
				$rootScope.$on('logout', function () {
382
					$scope.active_vault = null;
383
					$scope.credentials = [];
384
//				$scope.$parent.selectedVault = false;
385
386
				});
387
388
389
				$scope.downloadFile = function (credential, file) {
390
					var callback = function (result) {
391
						var key = null;
392
						if (!result.hasOwnProperty('file_data')) {
393
							NotificationService.showNotification($translate.instant('error.loading.file.perm'), 5000);
394
							return;
395
396
						}
397
						if (!credential.hasOwnProperty('acl') && credential.hasOwnProperty('shared_key')) {
398
							if (credential.shared_key) {
399
								key = EncryptService.decryptString(angular.copy(credential.shared_key));
400
							}
401
						}
402
						if (credential.hasOwnProperty('acl')) {
403
							key = EncryptService.decryptString(angular.copy(credential.acl.shared_key));
404
						}
405
406
						var file_data = EncryptService.decryptString(result.file_data, key);
407
						download(file_data, escapeHTML(file.filename), file.mimetype);
408
409
					};
410
411
					if (!credential.hasOwnProperty('acl')) {
412
						FileService.getFile(file).then(callback);
413
					} else {
414
						ShareService.downloadSharedFile(credential, file).then(callback);
415
					}
416
417
				};
418
419
			}]);
420
}());